package de.schule.barnimgymnasium.autotransporter.spiele;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.eclipse.swt.graphics.RGB;

import de.schule.barnimgymnasium.autotransporter.Stellplatz;
import de.schule.barnimgymnasium.autotransporter.Transporter;

public class SpielSpiel extends Spiel {

	Random zufallsgenerator = new Random();
	RGB farbe = null;
	List<Stellplatz> plaetze;
	List<RGB> verfuegbareFarben;
	int fehlerzaehler = 0;
	final int FEHLERANZAHL_HILFMIR = 5;

	enum Fehlertyp {
		FalscheFarbe
	};

	public SpielSpiel(final Transporter transporter) {
		super(transporter);
		this.definiereVerfuegbareFarben(transporter);
		this.stelleAufgabe();
	}

	@Override
	public void stellplatzGeaendert(Stellplatz s) {
		if (this.isAufgabeRichtigGeloest(s)) {
			this.stelleAufgabe();
		}
	}

	void definiereVerfuegbareFarben(final Transporter transporter) {
		this.verfuegbareFarben = new ArrayList<RGB>();
		for (final Stellplatz platz : transporter.getStellplaetze()) {
			if (platz.getAuto() != null) {
				final RGB c = platz.getAuto().getRgb();
				if (!this.verfuegbareFarben.contains(c)) {
					this.verfuegbareFarben.add(c);
				}
			}
		}
	}

	void stelleAufgabe() {
		this.farbe = this.waehleFarbe();
		this.plaetze = this.sucheFarbeAufTransporter(this.farbe);
		if (this.plaetze == null || this.plaetze.isEmpty()) {
			this.lautsprecher.say("Stelle das " + getAdjektiv(farbe)
					+ " Auto auf den Transporter");
		} else {
			this.lautsprecher.say("Nimm das " + getAdjektiv(farbe)
					+ " Auto vom Transporter.");
		}
	}

	private String getAdjektiv(RGB rgb) {

		return "unbekannte";
	}

	boolean isAufgabeRichtigGeloest(final Object obj) {
		if (this.plaetze == null) {
			// Ein Auto auf den Transporter stellen
			if (obj instanceof Stellplatz) {
				final Stellplatz platz = (Stellplatz) obj;
				if (platz.getAuto() == null) {
					// Das Auto wurde weggenommen, offensichtlich das mit der
					// falschen Farbe
					this.lautsprecher.say(this
							.getFehlertext(Fehlertyp.FalscheFarbe));
					return false;
				} else {
					// Ein auto wurde hingestellt
					if (platz.getAuto().getRgb() == this.farbe) {
						// Es hat die richtige Farbe, super :)
						return true;
					} else {
						// Es hat die falsche Farbe
						this.lautsprecher.say(this
								.getFehlertext(Fehlertyp.FalscheFarbe));
						return false;
					}
				}
			} else {
				// weiß auch nicht, das dürfte nicht passieren, Programmabsturz
				throw new IllegalArgumentException(
						"Im SpielEvent mit Type.Stellplatz ist als source kein Stellplatz enthalten.");
			}
		} else {
			// Ein Auto vom Transporter nehmen
			if (this.plaetze.contains(obj)) {
				// Es wurde ein Auto von eimen der Stellplätze genommen, die ein
				// Auto mit der gewünschten Farbe stand.
				return true;
			} else {
				return false;
			}
		}
	}

	private String getFehlertext(final Fehlertyp typ) {
		String ret;
		switch (typ) {
		case FalscheFarbe:
			ret = "Oh oh, das war nicht das " + getAdjektiv(farbe) + " Auto.";
		default:
			ret = null;
		}
		if (this.fehlerzaehler > this.FEHLERANZAHL_HILFMIR) {
			ret += " Frage jemanden um Rat.";
		} else {
			ret += " Versuche es noch einmal.";
		}
		return ret;
	}

	private RGB waehleFarbe() {
		final int x = this.zufallsgenerator.nextInt(this.verfuegbareFarben
				.size());
		return this.verfuegbareFarben.get(x);
	}

	private List<Stellplatz> sucheFarbeAufTransporter(final RGB farbe2) {
		final List<Stellplatz> ret = new ArrayList<Stellplatz>();
		for (final Stellplatz platz : transporter.getStellplaetze()) {
			if (platz.getAuto() != null) {
				if (platz.getAuto().getRgb() == farbe2) {
					ret.add(platz);
				}
			}
		}
		return ret;
	}

	@Override
	protected void begruessen() {
		say("Lass uns spielen");
	}
}
